package controlador;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;

import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

import modelo.Arbitro;
import modelo.Calendario;
import modelo.Equipo;
import modelo.Liga;

import vista.VistaGenerarCalendario;
import vista.VistaMenuPrincipal;
import vista.VistaModeloTablaGenerarCalendario;

public class ControladorVistaGenerarCalendario implements ActionListener {
	private VistaGenerarCalendario ventanaGenerarCalendario;
	private Liga laLiga;


	
	public ControladorVistaGenerarCalendario(Liga liga) {
		super();
		ventanaGenerarCalendario = new VistaGenerarCalendario();
		ventanaGenerarCalendario.setLocationRelativeTo(null);
		ventanaGenerarCalendario.setVisible(true);
		ventanaGenerarCalendario.agregarListener(this);
		this.laLiga = liga;
	}	
	
	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equalsIgnoreCase("Generar")){ 
			   generarCalendario();
		}else if(e.getActionCommand().equalsIgnoreCase("Salir")){
			ventanaGenerarCalendario.setVisible(false);
			ventanaGenerarCalendario.dispose();
		}
	}

	private void generarCalendario() {
		
		if (esFecha(ventanaGenerarCalendario.getTxtFechaInicio().getText())==false){
			ventanaGenerarCalendario.TirarMensajeError("Debe colocar una fecha de inicio valida");
			ventanaGenerarCalendario.getTxtFechaInicio().requestFocusInWindow();
		}else if (esPar(laLiga.getEquipos().size())==false){
			ventanaGenerarCalendario.TirarMensajeError("Para poder generar el calendario, la cantidad de equipos debe ser par");
		}else if (laLiga.getArbitros().size() < laLiga.getEquipos().size()/2){
		    ventanaGenerarCalendario.TirarMensajeError("El numero de arbitros no es suficiente para generar el calendario");
		 }else{   
			hacerTorneo();
		 }	
	}
	
	private boolean esFecha(String fechax) {
		try {
		SimpleDateFormat formatoFecha = new SimpleDateFormat("dd/MM/yyyy");
		formatoFecha.setLenient(false); // para que no corrija si ingresamos por ejemplo: 35 de febrero, si no que de error 
		Date fecha = formatoFecha.parse(fechax);
		} catch (Exception e) {
			return false;
		}
		return true;
	}
	
	private boolean esPar(int numero){
		if (((numero % 2) == 0)&&((numero/2) >0)) {
			return true;
		}else{ 
			return false;
		}
	}
	
	private Date incrementarFecha(Date fecha, int valor){
		Calendar cal = Calendar.getInstance(); 
		cal.setTime(fecha);
		cal.add(cal.DATE, 7);
		fecha = cal.getTime();
		return fecha;
	}
	
	private Date asignarFecha(String fechaStr){
		SimpleDateFormat formatoDeFecha = new SimpleDateFormat("dd/MM/yyyy");
		Date fecha=null;
		
		try {
			fecha = formatoDeFecha.parse(fechaStr);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return fecha;
	}
	

	
	private void partirEquipos(ArrayList <Equipo> equipos,ArrayList <Equipo> equiposA,ArrayList <Equipo> equiposB){
		int mitad = equipos.size()/2;
		
		for(int i=0;i<equipos.size();i++){
			if (i<mitad)
				equiposA.add((Equipo) equipos.get(i).clone());
			else
				equiposB.add((Equipo) equipos.get(i).clone());
		}
	}
	
	private void rotarEquipos(int cantidadEquipos,ArrayList <Equipo> equiposA,ArrayList <Equipo> equiposB){
		int posUltimoA = equiposA.size()-1;
		
		Equipo primeroB = (Equipo) equiposB.get(0).clone();	
		equiposB.remove(0);
		Equipo ultimoA = (Equipo) equiposA.get(posUltimoA).clone();
		equiposA.remove(posUltimoA);
		equiposB.add(ultimoA);
		
		Equipo fijo = (Equipo) equiposA.get(0).clone();
		equiposA.remove(0);
		equiposA.add(0, primeroB);
		equiposA.add(0, fijo);
			
			
	}
	
	private void hacerTorneo(){
		ArrayList <Equipo> equiposA = new ArrayList <Equipo>();
		ArrayList <Equipo> equiposB = new ArrayList <Equipo>();
		ArrayList <Equipo> equipos = laLiga.getEquipos();
		ArrayList<Calendario> listaJuegos= laLiga.getCalendario();
		String fechaStr = ventanaGenerarCalendario.getTxtFechaInicio().getText();
		int cantidadEquipos = laLiga.getEquipos().size();
		
		listaJuegos.clear();
		laLiga.inicializarEstadisticas();
		partirEquipos(equipos,equiposA,equiposB);
		
		for(int i=0;i<cantidadEquipos-1;i++){
			for (int j=0;j<cantidadEquipos/2;j++){
				Equipo local= (Equipo) equiposA.get(j).clone();
				Equipo visitante= (Equipo) equiposB.get(j).clone();
				listaJuegos.add(new Calendario(fechaStr,local, visitante, new Arbitro()));
			}
			rotarEquipos(cantidadEquipos,equiposA,equiposB);
		}
		
		
		colocarFechasJuegos(listaJuegos,fechaStr);
		asignarArbitros(listaJuegos);
		colocarGolesJuegos(listaJuegos);
		ventanaGenerarCalendario.setListado(new VistaModeloTablaGenerarCalendario(listaJuegos));
		
	}
	
	private void colocarFechasJuegos(ArrayList<Calendario> listaJuegos, String fechaStr){
		SimpleDateFormat formatoDeFecha = new SimpleDateFormat("dd/MM/yyyy");
		Date fecha=null;
		int cantidadJuegosSemana = laLiga.getEquipos().size()/2;
		fecha = asignarFecha(fechaStr);
		
		int k=0;
		for(int i=0;i<listaJuegos.size();i=i+cantidadJuegosSemana){
			for(int j=0;j<cantidadJuegosSemana;j++){
				listaJuegos.get(k).setFecha(formatoDeFecha.format(fecha));
				k++;
			}
			fecha = incrementarFecha(fecha,7);
		}
		Collections.sort(listaJuegos);
		hacerSegundaVuelta(listaJuegos,formatoDeFecha.format(fecha));
	}
	
	private void colocarGoleadores(int posActual,int golLocal, int golVisitante,ArrayList<Calendario> listaJuegos){
		for (int i=1;i<=golLocal;i++){
			int jugador = (int) Math.floor(Math.random()*11);
			String codigo = listaJuegos.get(posActual).getLocal().getCodigo();
			int pos = laLiga.getPosicionEquipoArray(codigo);
			int golesAnteriores = laLiga.getEquipos().get(pos).getListaJugadores().get(jugador).getGolesAnotados();
			laLiga.getEquipos().get(pos).getListaJugadores().get(jugador).setGolesAnotados(golesAnteriores+1);
			listaJuegos.get(posActual).getGoleadores().add(laLiga.getEquipos().get(pos).getListaJugadores().get(jugador));
		}
		
		for (int i=1;i<=golVisitante;i++){
			int jugador = (int) Math.floor(Math.random()*11);
			String codigo = listaJuegos.get(posActual).getVisitante().getCodigo();
			int pos = laLiga.getPosicionEquipoArray(codigo);
			int golesAnteriores = laLiga.getEquipos().get(pos).getListaJugadores().get(jugador).getGolesAnotados();
			laLiga.getEquipos().get(pos).getListaJugadores().get(jugador).setGolesAnotados(golesAnteriores+1);
			listaJuegos.get(posActual).getGoleadores().add(laLiga.getEquipos().get(pos).getListaJugadores().get(jugador));
		}
	}
	
	private void colocarGolesEquipo(int posActual,int golLocal, int golVisitante,ArrayList<Calendario> listaJuegos){
		//local
		String codigo = listaJuegos.get(posActual).getLocal().getCodigo();
		int posLocal = laLiga.getPosicionEquipoArray(codigo);
		int golesFavorAnterior = laLiga.getEquipos().get(posLocal).getGolesFavor();
		laLiga.getEquipos().get(posLocal).setGolesFavor(golesFavorAnterior+golLocal);
		int golesContraAnterior = laLiga.getEquipos().get(posLocal).getGolesContra();
		laLiga.getEquipos().get(posLocal).setGolesContra(golesContraAnterior+golVisitante);
		
		//visitante
		codigo = listaJuegos.get(posActual).getVisitante().getCodigo();
		int posVisitante = laLiga.getPosicionEquipoArray(codigo);
		golesFavorAnterior = laLiga.getEquipos().get(posVisitante).getGolesFavor();
		laLiga.getEquipos().get(posVisitante).setGolesFavor(golesFavorAnterior+golVisitante);
		golesContraAnterior = laLiga.getEquipos().get(posVisitante).getGolesContra();
		laLiga.getEquipos().get(posVisitante).setGolesContra(golesContraAnterior+golLocal);
		
		//sumar ganados o perdidos
		if (golLocal == golVisitante){
			//local
			int juegosEmpatadosAnterior = laLiga.getEquipos().get(posLocal).getJuegosEmpatados();
			laLiga.getEquipos().get(posLocal).setJuegosEmpatados(juegosEmpatadosAnterior+1);
			int puntosAcumulados = laLiga.getEquipos().get(posLocal).getPuntosAcumulados();
			laLiga.getEquipos().get(posLocal).setPuntosAcumulados(puntosAcumulados+1);

			//visitante
			juegosEmpatadosAnterior = laLiga.getEquipos().get(posVisitante).getJuegosEmpatados();
			laLiga.getEquipos().get(posVisitante).setJuegosEmpatados(juegosEmpatadosAnterior+1);
			puntosAcumulados = laLiga.getEquipos().get(posVisitante).getPuntosAcumulados();
			laLiga.getEquipos().get(posVisitante).setPuntosAcumulados(puntosAcumulados+1);
		}
		else if (golLocal > golVisitante){
			//local gano
			int juegosGanadosAnterior = laLiga.getEquipos().get(posLocal).getJuegosGanados(); 
			laLiga.getEquipos().get(posLocal).setJuegosGanados(juegosGanadosAnterior+1);
			int puntosAcumulados = laLiga.getEquipos().get(posLocal).getPuntosAcumulados();
			laLiga.getEquipos().get(posLocal).setPuntosAcumulados(puntosAcumulados+3);
			//visitante perdio
			int juegosPerdidosAnterior = laLiga.getEquipos().get(posVisitante).getJuegosPerdidos(); 
			laLiga.getEquipos().get(posVisitante).setJuegosPerdidos(juegosPerdidosAnterior+1);
			
		}else{
			//visitante gano
			int juegosGanadosAnterior = laLiga.getEquipos().get(posVisitante).getJuegosGanados(); 
			laLiga.getEquipos().get(posVisitante).setJuegosGanados(juegosGanadosAnterior+1);
			int puntosAcumulados = laLiga.getEquipos().get(posVisitante).getPuntosAcumulados();
			laLiga.getEquipos().get(posVisitante).setPuntosAcumulados(puntosAcumulados+3);
			//local perdio
			int juegosPerdidosAnterior = laLiga.getEquipos().get(posLocal).getJuegosPerdidos(); 
			laLiga.getEquipos().get(posLocal).setJuegosPerdidos(juegosPerdidosAnterior+1);
		}
		
	}
	
	private void colocarGolesJuegos( ArrayList<Calendario> listaJuegos){
		int i =0,golLocal=0,golVisitante=0;
		
		for (i=0;i<listaJuegos.size();i++){
			//hacemos los goles
			golLocal = (int) Math.floor(Math.random()*6);
			golVisitante = (int) Math.floor(Math.random()*6);
			listaJuegos.get(i).getLocal().setGolesFavor(golLocal);
			listaJuegos.get(i).getLocal().setGolesContra(golVisitante);
			listaJuegos.get(i).getVisitante().setGolesFavor(golVisitante);
			listaJuegos.get(i).getVisitante().setGolesContra(golLocal);

			colocarGolesEquipo(i,golLocal,golVisitante,listaJuegos);
			
			System.out.println(listaJuegos.get(i).getLocal().getNombre()+" "+listaJuegos.get(i).getVisitante().getNombre());
			System.out.println(golLocal+" "+golVisitante);
			colocarGoleadores(i,golLocal,golVisitante,listaJuegos);
			
		}
		
	}
	
	
	private void asignarArbitros(ArrayList<Calendario> listaJuegos){
		ArrayList<Arbitro> arbitros = laLiga.getArbitros();
		int cantidadArbitros = arbitros.size()-1,a=0;
		
		for(int i=0;i<listaJuegos.size();i++){
			listaJuegos.get(i).setArbitro(arbitros.get(a));
			if (a == cantidadArbitros){
				a = 0;
			}else{
				a++;
			}
		}
		
	}
	
	
	private void hacerSegundaVuelta(ArrayList<Calendario> listaJuegos, String fechaFinPrimeraVuelta){
		SimpleDateFormat formatoDeFecha = new SimpleDateFormat("dd/MM/yyyy");
		int fin = listaJuegos.size();
		Date fecha=null;
		int incremento = laLiga.getEquipos().size()/2;
		
		fecha=asignarFecha(fechaFinPrimeraVuelta);
		//recorre la lista de juegos y por cada uno inserta un item al final cambiando local por visitante
		int a=0;
		for (int i=0;i<fin;i=i+incremento){
			for (int j=0; j<incremento;j++){
				Equipo local = (Equipo) listaJuegos.get(a).getVisitante().clone();
				Equipo visitante = (Equipo) listaJuegos.get(a).getLocal().clone();
				listaJuegos.add(new Calendario(formatoDeFecha.format(fecha),local,visitante,new Arbitro()));
				a++;
			}
			fecha=incrementarFecha(fecha,7);
		}
	}
	

}
